package system

import (
	"context"
	"gf_blog_admin/internal/dao"
	"gf_blog_admin/internal/model"
	"gf_blog_admin/internal/service"
	"gf_blog_admin/utility/utils"
	"github.com/gogf/gf/v2/database/gdb"
	"github.com/gogf/gf/v2/errors/gerror"
)

type sSysDict struct{}

func init() {
	service.RegisterSysDict(NewSysDict())
}

func NewSysDict() *sSysDict {
	return &sSysDict{}
}

func (s *sSysDict) List(ctx context.Context) (out []*model.DictItem, err error) {
	cls := dao.BlSysDict.Columns()
	out = make([]*model.DictItem, 0)
	err = dao.BlSysDict.Ctx(ctx).
		Fields(cls.Id, cls.DictName, cls.DictCode, cls.DictStatus).
		Scan(&out)
	return
}

func (s *sSysDict) Detail(ctx context.Context, id uint64) (out *model.DictItem, err error) {
	cls := dao.BlSysDict.Columns()
	err = dao.BlSysDict.Ctx(ctx).Where(cls.Id, id).Scan(&out)
	if err != nil {
		return nil, err
	}
	if out == nil {
		return nil, gerror.New("数据不存在")
	}
	return
}

func (s *sSysDict) Store(ctx context.Context, in *model.DictFormInput) (err error) {
	cls := dao.BlSysDict.Columns()

	if err = utils.IsUnique(ctx, &dao.BlSysDict, map[string]string{
		cls.DictCode: in.DictCode,
	}, "字典编码已存在"); err != nil {
		return err
	}

	err = dao.BlSysDict.Transaction(ctx, func(ctx context.Context, tx gdb.TX) error {
		_, err = dao.BlSysDict.Ctx(ctx).Data(in).Insert()
		return err
	})
	return
}

func (s *sSysDict) Update(ctx context.Context, id uint64, in *model.DictFormInput) (err error) {
	cls := dao.BlSysDict.Columns()

	if err = utils.IsUnique(ctx, &dao.BlSysDict, map[string]interface{}{
		cls.Id + " !=": id,
		cls.DictCode:   in.DictCode,
	}, "字典编码已存在"); err != nil {
		return err
	}

	if _, err = s.Detail(ctx, id); err != nil {
		return err
	}

	err = dao.BlSysDict.Transaction(ctx, func(ctx context.Context, tx gdb.TX) error {
		_, err = dao.BlSysDict.Ctx(ctx).Where(cls.Id, id).Data(in).Update()
		return err
	})
	return
}

func (s *sSysDict) Destroy(ctx context.Context, ids []uint64) (err error) {
	var (
		check bool
		cls   = dao.BlSysDict.Columns()
		m     = dao.BlSysDict.Ctx(ctx)
	)

	ids = utils.UniqueIds(ids)
	if check, err = m.WhereIn(cls.Id, ids).Exist(); err != nil {
		return err
	} else if !check {
		return gerror.New("操作失败")
	}

	err = dao.BlSysDict.Transaction(ctx, func(ctx context.Context, tx gdb.TX) error {
		_, err = m.WhereIn(cls.Id, ids).Delete()
		return err
	})
	return
}
